package com.inifitness.sms.service;

import java.time.LocalDate;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

import com.aliyun.sdk.service.dysmsapi20170525.models.AddShortUrlResponseBody;
import com.aliyun.sdk.service.dysmsapi20170525.models.AddSmsSignRequest;
import com.aliyun.sdk.service.dysmsapi20170525.models.AddSmsSignResponseBody;
import com.aliyun.sdk.service.dysmsapi20170525.models.AddSmsTemplateResponseBody;
import com.aliyun.sdk.service.dysmsapi20170525.models.DeleteShortUrlResponseBody;
import com.aliyun.sdk.service.dysmsapi20170525.models.DeleteSmsSignResponseBody;
import com.aliyun.sdk.service.dysmsapi20170525.models.DeleteSmsTemplateResponseBody;
import com.aliyun.sdk.service.dysmsapi20170525.models.ModifySmsSignRequest;
import com.aliyun.sdk.service.dysmsapi20170525.models.ModifySmsSignResponseBody;
import com.aliyun.sdk.service.dysmsapi20170525.models.ModifySmsTemplateResponseBody;
import com.aliyun.sdk.service.dysmsapi20170525.models.QuerySendStatisticsResponseBody;
import com.aliyun.sdk.service.dysmsapi20170525.models.QueryShortUrlResponseBody;
import com.aliyun.sdk.service.dysmsapi20170525.models.QuerySmsSignListResponseBody;
import com.aliyun.sdk.service.dysmsapi20170525.models.QuerySmsSignResponseBody;
import com.aliyun.sdk.service.dysmsapi20170525.models.QuerySmsTemplateListResponseBody;
import com.aliyun.sdk.service.dysmsapi20170525.models.QuerySmsTemplateResponseBody;
import com.aliyun.sdk.service.dysmsapi20170525.models.SendBatchSmsResponseBody;
import com.aliyun.sdk.service.dysmsapi20170525.models.SendSmsResponseBody;
import com.inifitness.sms.constants.SignSourceEnum;
import com.inifitness.sms.constants.SignTypeEnum;
import com.inifitness.sms.constants.TemplateTypeEnum;

import cn.hutool.core.builder.EqualsBuilder;
import cn.hutool.core.builder.HashCodeBuilder;
import lombok.AccessLevel;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.Setter;

/**
 * @author mageric
 * @version 1.0.0
 * @since 2023/1/10 14:38
 */
public interface AliCloudSmsService {

  /**
   * 发送单条短信
   *
   * @param message      发送信息
   * @param templateCode 模板编码
   * @return 发送结果
   */
  SendSmsResponseBody sendSms(Message message, String templateCode);

  /**
   * 批量发送短信
   *
   * @param messages     发送信息
   * @param templateCode 模板编码
   * @return 发送结果
   */
  SendBatchSmsResponseBody sendBatchSms(Set<Message> messages, String templateCode);

  /**
   * 查询短信发送统计信息
   *
   * @param startDate 开始日期
   * @param endData   结束日期
   * @param pageIndex 当前页码
   * @param pageSize  每页显示的条数
   * @return 短信发送统计信息
   */
  QuerySendStatisticsResponseBody querySendStatistics(LocalDate startDate, LocalDate endData,
      Integer pageIndex, Integer pageSize);

  /**
   * 查询短信发送统计信息
   *
   * @param startDate    开始日期
   * @param endData      结束日期
   * @param pageIndex    当前页码
   * @param pageSize     每页显示的条数
   * @param templateType 模板类型
   * @return 短信发送统计信息
   */
  QuerySendStatisticsResponseBody querySendStatistics(LocalDate startDate, LocalDate endData,
      Integer pageIndex, Integer pageSize, TemplateTypeEnum templateType);

  /**
   * 查询短信发送统计信息
   *
   * @param startDate 开始日期
   * @param endData   结束日期
   * @param pageIndex 当前页码
   * @param pageSize  每页显示的条数
   * @param signName  签名名称
   * @return 短信发送统计信息
   */
  QuerySendStatisticsResponseBody querySendStatistics(LocalDate startDate, LocalDate endData,
      Integer pageIndex, Integer pageSize, String signName);

  /**
   * 查询短信发送统计信息
   *
   * @param startDate    开始日期
   * @param endData      结束日期
   * @param pageIndex    当前页码
   * @param pageSize     每页显示的条数
   * @param templateType 模板类型
   * @param signName     签名名称
   * @return 短信发送统计信息
   */
  QuerySendStatisticsResponseBody querySendStatistics(LocalDate startDate, LocalDate endData,
      Integer pageIndex, Integer pageSize, TemplateTypeEnum templateType, String signName);

  /**
   * 申请短信签名
   *
   * @param signName 短信签名
   * @param fileList 证明文件
   * @return 申请短信签名结果
   */
  AddSmsSignResponseBody addSmsSign(String signName, List<AddSmsSignRequest.SignFileList> fileList);

  /**
   * 申请短信签名
   *
   * @param signName   短信签名
   * @param signSource 签名来源
   * @param remark     场景说明
   * @param fileList   证明文件
   * @return 申请短信签名结果
   */
  AddSmsSignResponseBody addSmsSign(String signName, SignSourceEnum signSource, String remark,
      List<AddSmsSignRequest.SignFileList> fileList);

  /**
   * 申请短信签名
   *
   * @param signName   短信签名
   * @param signSource 签名来源
   * @param remark     场景说明
   * @param signType   签名类型 0，验证码 1通用
   * @param fileList   证明文件
   * @return 申请短信签名结果
   */
  AddSmsSignResponseBody addSmsSign(String signName, SignSourceEnum signSource, String remark,
      SignTypeEnum signType, List<AddSmsSignRequest.SignFileList> fileList);

  /**
   * 删除短信签名
   *
   * @param signName 短信签名
   * @return 删除短信签名结果
   */
  DeleteSmsSignResponseBody deleteSmsSign(String signName);

  /**
   * 修改短信签名
   *
   * @param signName 短信签名
   * @param fileList 证明文件
   * @return 修改短信签名结果
   */
  ModifySmsSignResponseBody modifySmsSign(String signName,
      List<ModifySmsSignRequest.SignFileList> fileList);

  /**
   * 修改短信签名
   *
   * @param signName   短信签名
   * @param signSource 签名来源
   * @param remark     场景说明
   * @param fileList   证明文件
   * @return 修改短信签名结果
   */
  ModifySmsSignResponseBody modifySmsSign(String signName, SignSourceEnum signSource, String remark,
      List<ModifySmsSignRequest.SignFileList> fileList);

  /**
   * 修改短信签名
   *
   * @param signName   短信签名
   * @param signSource 签名来源
   * @param remark     场景说明
   * @param signType   签名类型 0，验证码 1通用
   * @param fileList   证明文件
   * @return 修改短信签名结果
   */
  ModifySmsSignResponseBody modifySmsSign(String signName, SignSourceEnum signSource, String remark,
      SignTypeEnum signType, List<ModifySmsSignRequest.SignFileList> fileList);

  /**
   * 查询短信签名列表
   *
   * @param pageIndex 页码
   * @param pageSize  每页显示数量
   * @return 短信签名列表「 QuerySmsSignListResponseBody.SmsSignList[0].AuditStatus使用AuditStatus.name进行判断
   */
  QuerySmsSignListResponseBody querySmsSignList(Integer pageIndex, Integer pageSize);

  /**
   * 查询短信签名申请状态
   *
   * @param signName 签名
   * @return 短信签名申请状态 SignStatus 使用AuditStatus.getCode()进行判断
   */
  QuerySmsSignResponseBody querySmsSign(String signName);

  /**
   * 添加短信模板
   *
   * @param templateType    模板类型
   * @param templateName    模板名称
   * @param templateContent 模板内容
   * @param remark          场景模板
   * @return 短信模板添加结果
   */
  AddSmsTemplateResponseBody addSmsTemplate(TemplateTypeEnum templateType, String templateName,
      String templateContent, String remark);

  /**
   * 删除模板
   *
   * @param templateCode 模板编码
   * @return 删除模板结果
   */
  DeleteSmsTemplateResponseBody deleteSmsTemplate(String templateCode);

  /**
   * 修改模板
   *
   * @param templateCode    模板编码
   * @param templateType    买本类型
   * @param templateName    模板名称
   * @param templateContent 模板内容
   * @param remark          场景说明
   * @return 修改模板结果
   */
  ModifySmsTemplateResponseBody modifySmsTemplate(String templateCode,
      TemplateTypeEnum templateType, String templateName, String templateContent, String remark);

  /**
   * 查询短信模板列表详情
   *
   * @param pageIndex 页码
   * @param pageSize  每页显示数量
   * @return 短信模板列表详情 TemplateStatus 使用AuditStatus.getCode() 进行判断审核状态P
   */
  QuerySmsTemplateListResponseBody querySmsTemplateList(Integer pageIndex, Integer pageSize);

  /**
   * 查询模板信息
   *
   * @param templateCode 模板编码
   * @return 模板信息 QuerySmsTemplateListResponseBody.SmsTemplateList[0].AuditStatus
   * 使用AuditStatus.name进行判断
   */
  QuerySmsTemplateResponseBody querySmsTemplate(String templateCode);

  /**
   * 创建短链
   *
   * @param sourceUrl     原始链接地址
   * @param shortUrlName  短链服务名称
   * @param effectiveDays 短链服务使用有效期
   * @return 创建短链结果
   */
  AddShortUrlResponseBody addShortUrl(String sourceUrl, String shortUrlName, Integer effectiveDays);

  /**
   * 删除短链 删除后短链将无法使用，无法还原为原链
   *
   * @param sourceUrl 原链
   * @return 删除短链结果
   */
  DeleteShortUrlResponseBody deleteShortUrl(String sourceUrl);

  /**
   * 查询短链状态 可判断短链是否可用
   *
   * @param shortUrl 生成的短链服务地址
   * @return 短链状态 ShortUrlStatus 使用ShortUrlStatus.getCode()进行判断
   */
  QueryShortUrlResponseBody queryShortUrl(String shortUrl);

  @Data
  @AllArgsConstructor
  class Message {

    @Setter(AccessLevel.NONE)
    private final Map<String, String> parameters = HashMap.newHashMap(4);
    private String mobile;
    private String signName;

    public Message addParameter(String key, String value) {
      this.parameters.put(key, value);
      return this;
    }

    public Message addParameters(Map<String, String> map) {
      this.parameters.putAll(map);
      return this;
    }


    @Override
    public boolean equals(Object o) {
      if (this == o) {
        return true;
      }

      if (o == null || getClass() != o.getClass()) {
        return false;
      }

      Message message = (Message) o;

      return new EqualsBuilder().append(mobile, message.mobile).isEquals();
    }

    @Override
    public int hashCode() {
      return new HashCodeBuilder(17, 37).append(mobile).toHashCode();
    }
  }

  @Data
  @AllArgsConstructor
  class DelayedMessage {

    private String templateCode;
    private String msgId;
    private Set<Message> messages;
  }
}
